package pe.com.cotelasa.scp.dao.impl;

import java.io.Serializable;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Collection;
import java.util.Date;
import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import pe.com.cotelasa.common.dao.excepcion.DAOException;
import pe.com.cotelasa.common.dao.DaoImpl;
import pe.com.cotelasa.scp.dao.IDAOCompraFacturacion;
import pe.com.cotelasa.scp.dominio.common.ESTADO_REGISTRO;
import pe.com.cotelasa.scp.dominio.common.util.UtilitarioFecha;
import pe.com.cotelasa.scp.entidad.CompraFacturacion;
import pe.com.cotelasa.scp.entidad.DetalleCompraFacturacion;
import pe.com.cotelasa.scp.entidad.OrdenCompraServicio;

@SuppressWarnings("unchecked")
@Repository("daoCompraFacturacion")
public class DAOCompraFacturacionImpl extends DaoImpl<CompraFacturacion, Integer> implements IDAOCompraFacturacion, Serializable {

    private static final long serialVersionUID = 1L;
    @Autowired
    private SessionFactory sessionFactory;

    @Transactional(readOnly = true)
    public CompraFacturacion obtenerFacturaPorNumero(String numeroFactura) throws DAOException {
        CompraFacturacion facuraBuscada = null;
        try {
            sessionFactory.getCurrentSession().flush();
            facuraBuscada = (CompraFacturacion) sessionFactory.getCurrentSession().createCriteria(CompraFacturacion.class)
                    .add(Restrictions.eq("numeroFactura", numeroFactura))
                    .add(Restrictions.eq("estadoRegistro", ESTADO_REGISTRO.ACTIVO.getValor())).uniqueResult();
        } catch (Exception e) {
            throw new DAOException(e.getMessage(), e);
        }
        return facuraBuscada;
    }

    @Override
    public Collection<CompraFacturacion> obtenerFacturasProduccion() throws DAOException {
        Collection<CompraFacturacion> listaFacturaProduccion = null;
        try {
            sessionFactory.getCurrentSession().flush();
            listaFacturaProduccion = sessionFactory.getCurrentSession().createCriteria(CompraFacturacion.class)
                    .add(Restrictions.isNotNull("idOrdenPedido"))
                    .add(Restrictions.eq("estadoRegistro", ESTADO_REGISTRO.ACTIVO.getValor())).list();
        } catch (Exception e) {
            throw new DAOException(e.getMessage(), e);
        }
        return listaFacturaProduccion;
    }

    @Override
    public Collection<CompraFacturacion> buscarCompraFacturacionPorFiltro(CompraFacturacion factura, Date fechaInicio, Date fechaFinal) throws DAOException {
        Collection<CompraFacturacion> listaFacturaProduccion = null;
        try {
            sessionFactory.getCurrentSession().flush();
            Criteria query = sessionFactory.getCurrentSession().createCriteria(CompraFacturacion.class)
                    .addOrder(Order.desc("id"))
                    .createAlias("idProveedor", "p")
                    .add(Restrictions.eq("estadoRegistro", ESTADO_REGISTRO.ACTIVO.getValor()))
                    .add(Restrictions.like("numeroFactura", "%" + factura.getNumeroFactura() + "%"))
                    .add(Restrictions.eq("tipoCompPago", factura.getTipoCompPago()))
                    .add(Restrictions.eq("idEmpresa", factura.getIdEmpresa()))
                    .add(Restrictions.like("p.razonSocial", "%" + factura.getIdProveedor().getRazonSocial() + "%"));
            
            if (factura.getEstadoCancelacion() != '0') {
                query = query.add(Restrictions.eq("estadoCancelacion", factura.getEstadoCancelacion()));
            }

            if (factura.getIdOrdenPedido().getId() == 0) {
                query = query.add(Restrictions.isNull("idOrdenPedido"));
            } else if (factura.getIdOrdenPedido().getId() != -1) {
                query = query.add(Restrictions.eq("idOrdenPedido.id", factura.getIdOrdenPedido().getId()));
            }

            if (factura.getIdOrdenCompraServicio().getId() == 0) {
                query = query.add(Restrictions.isNull("idOrdenCompraServicio"));
            } else if (factura.getIdOrdenCompraServicio().getId() != -1) {
                query = query.add(Restrictions.eq("idOrdenCompraServicio.id", factura.getIdOrdenCompraServicio().getId()));
            }


            if (fechaInicio == null && fechaFinal == null) {
                listaFacturaProduccion = query.list();
            } else if (fechaInicio != null && fechaFinal != null) {
                listaFacturaProduccion = query.add(Restrictions.ge("fecEmision", fechaInicio)).add(Restrictions.le("fecEmision", fechaFinal)).list();
            } else if (fechaInicio == null) {
                listaFacturaProduccion = query.add(Restrictions.le("fecEmision", fechaFinal)).list();
            } else if (fechaFinal == null) {
                listaFacturaProduccion = query.add(Restrictions.ge("fecEmision", fechaInicio)).list();
            }


        } catch (Exception e) {
            throw new DAOException(e.getMessage(), e);
        }

        return listaFacturaProduccion;
    }

    @Override
    public CompraFacturacion conseguirMasAntiguo(int idEmpresa) throws DAOException {
        sessionFactory.getCurrentSession().flush();
        return (CompraFacturacion) sessionFactory.getCurrentSession().createCriteria(CompraFacturacion.class)
                .addOrder(Order.asc("fecEmision"))
                .add(Restrictions.eq("idEmpresa.id", idEmpresa))
                .add(Restrictions.eq("estadoRegistro", ESTADO_REGISTRO.ACTIVO.getValor()))
                .setMaxResults(1)
                .uniqueResult();
    }

    @Override
    public CompraFacturacion conseguirMasNuevo(int idEmpresa) throws DAOException {
        sessionFactory.getCurrentSession().flush();
        return (CompraFacturacion) sessionFactory.getCurrentSession().createCriteria(CompraFacturacion.class)
                .addOrder(Order.desc("fecEmision"))
                .add(Restrictions.eq("idEmpresa.id", idEmpresa))
                .add(Restrictions.eq("estadoRegistro", ESTADO_REGISTRO.ACTIVO.getValor()))
                .setMaxResults(1)
                .uniqueResult();
    }

    @Override
    public BigDecimal buscarMontoPorMes(DetalleCompraFacturacion detalle, Date fecha, int idEmpresa) throws DAOException {
        sessionFactory.getCurrentSession().flush();
        /*System.out.println("fecha 1: "+fecha);
        System.out.println("fecha 2: "+UtilitarioFecha.agregarMesesFecha(fecha,1));
        System.out.println("idEmpresa: "+idEmpresa);*/
        Criteria cr = sessionFactory.getCurrentSession().createCriteria(DetalleCompraFacturacion.class)
                .createAlias("idArticulo", "art")
                .createAlias("art.idCategoriaArticulo", "subCat")
                .createAlias("idFactura", "fac")
                .add(Restrictions.eq("subCat.idCategoriaArticulo", detalle.getIdArticulo().getIdCategoriaArticulo()))
                .add(Restrictions.le("fac.fecEmision", UtilitarioFecha.agregarMesesFecha(fecha,1)))
                .add(Restrictions.ge("fac.fecEmision", fecha))
                //.add(Restrictions.between("fac.fecEmision", fecha, UtilitarioFecha.obtenerUltimoDiaMes(fecha)))
                .add(Restrictions.eq("estadoRegistro", ESTADO_REGISTRO.ACTIVO.getValor()))
                .add(Restrictions.eq("fac.estadoRegistro", ESTADO_REGISTRO.ACTIVO.getValor()))
                .add(Restrictions.eq("fac.idEmpresa.id", idEmpresa))
                .setProjection(Projections.sum("precioTotal"));

        List total = cr.list();
        /*System.out.println(total);
        System.out.println("total = " + total.get(0));*/
        return (BigDecimal) (total.get(0));
        //return BigDecimal.ZERO;
    }
    
    @Override
    public Collection<CompraFacturacion> buscarFacturasParaLetras(
    		Integer idProveedor, Integer idMoneda, String tipoPago,
    		String estadoCancelacion, Character estadoRegistro)
    		throws DAOException {
    	 Criteria cr = sessionFactory.getCurrentSession().createCriteria(CompraFacturacion.class);
    	 cr.add(Restrictions.eq("idProveedor.id",idProveedor));
    	 cr.add(Restrictions.eq("idTipoMoneda.id",idMoneda));
    	 cr.add(Restrictions.eq("tipoPago",tipoPago));
    	 cr.add(Restrictions.eq("estadoCancelacion",estadoCancelacion));
    	 cr.add(Restrictions.eq("estadoRegistro",estadoRegistro));
    	 cr.add(Restrictions.eq("tipoCompPago",11));
    	return cr.list();
    }
    
    @Override
    public Collection<CompraFacturacion> obtenerCompraFacturacion(
    		Integer idProveedor, Integer idMoneda,
    		String estadoCancelacion, Character estadoRegistro,String numFactura)
    		throws DAOException {
    	 Criteria cr = sessionFactory.getCurrentSession().createCriteria(CompraFacturacion.class);
    	 if(idProveedor!=null && idProveedor!=0){
    		 cr.add(Restrictions.eq("idProveedor.id",idProveedor));
    	 }
    	 if(idMoneda!=null && idMoneda != 0){
    		 cr.add(Restrictions.eq("idTipoMoneda.id",idMoneda));
    	 }	 
    	 
    	 if(numFactura!=null && numFactura.length()>0){
    		 cr.add(Restrictions.eq("numeroFactura",numFactura));
    	 }
    	 cr.add(Restrictions.eq("estadoCancelacion",estadoCancelacion));
    	 cr.add(Restrictions.eq("estadoRegistro",estadoRegistro));
    	 cr.add(Restrictions.eq("tipoCompPago",11));
    	 System.out.println(" " + idProveedor + " " + idMoneda + " "+ estadoCancelacion + " " + estadoRegistro);
    	return cr.list();
    }
    
    @Override
    public void actualizarFacturasPagadas(
    		List<CompraFacturacion> listaCompraFacturacion) throws DAOException {
    	Session session = sessionFactory.getCurrentSession();
    	for (CompraFacturacion compraFacturacion : listaCompraFacturacion) {
    		Query query = session.createQuery("UPDATE CompraFacturacion SET estadoCancelacion "+ compraFacturacion.getEstadoCancelacion() + " WHERE id = " + compraFacturacion.getId());
        	query.executeUpdate();
		}
    	
    	
    }
}
